package com.bank.basic.util;

import com.bank.model.entity.*;
import com.bank.model.enums.*;
import com.bank.model.vo.deposit.CashDepositVo;
import com.bank.model.vo.deposit.DepositAddVo;
import com.bank.model.vo.loan.LoanVo;
import com.bank.model.vo.notice.NoticeAddVo;
import com.bank.model.vo.standard.StandardVo;
import com.bank.model.vo.transfer.TransferVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Cejay1314
 * @version 1.0
 * @create 2023/3/25 23:46
 */
@Component
public class EntityFactory {
    @Autowired
    MapperFactory mapperFactory;
    Map<String,Standard> standardsMap;
    Deposit deposit;
    Account account;
    Loan loan;
    Transfer transfer;
    FileConnect fileConnect;
    File file;
    Notice notice;
    Standard standard;

    @Autowired
    public void initStandardsMap(){
        this.standardsMap = new HashMap<>();
        List<Standard> standards = mapperFactory.getStandardMapper().selectList(null);
        for (Standard item:standards) {
            standardsMap.put(item.getName(),item);
        }
    }

    public Map<String,Standard> getStandardsMap(){
        return this.standardsMap;
    }

    public void initDeposit(){
        this.deposit = new Deposit();
        this.deposit.setDuration("0");
    }
    public Deposit getDeposit(CashDepositVo cashDepositVo){
        initDeposit();
        QueryWrapper<Deposit> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",cashDepositVo.getUsername());
        this.deposit.setUserId(mapperFactory.getDepositMapper().selectOne(queryWrapper).getUserId());
        this.deposit.setStatus(DepositStatusEnum.ING.getCode());
        this.deposit.setType(DepositTypeEnum.valueOf(cashDepositVo.getType()).getCode());
        this.deposit.setMoney(cashDepositVo.getMoney().toString());
        this.deposit.setDuration(cashDepositVo.getDuration().toString());
        this.deposit.setCreatedTime(cashDepositVo.getCreateTime());
        this.deposit.setUpdatedTime(cashDepositVo.getCreateTime());
        if(this.deposit.getType() == DepositTypeEnum.DemandDeposit.getCode()){
            this.deposit.setInterestRate(standardsMap.get("DemandDepositInterestRate").getContent());
        }else if(this.deposit.getType() == DepositTypeEnum.FixedDeposit.getCode()){
            this.deposit.setInterestRate(standardsMap.get("DemandDepositInterestRate").getContent());
        }
        return this.deposit;
    }
    public Deposit getDeposit(long userId,DepositAddVo depositAddVo){
        initDeposit();
        this.deposit.setUserId(userId);
        this.deposit.setAccountId(depositAddVo.getAccountId());
        this.deposit.setStatus(DepositStatusEnum.ING.getCode());
        this.deposit.setType(DepositTypeEnum.valueOf(depositAddVo.getType()).getCode());
        this.deposit.setMoney(depositAddVo.getMoney().toString());
        this.deposit.setDuration(depositAddVo.getDuration().toString());
        this.deposit.setCreatedTime(depositAddVo.getCreateTime());
        this.deposit.setUpdatedTime(depositAddVo.getCreateTime());
        if(this.deposit.getType() == DepositTypeEnum.DemandDeposit.getCode()){
            this.deposit.setInterestRate(standardsMap.get("DemandDepositInterestRate").getContent());
        }else if(this.deposit.getType() == DepositTypeEnum.FixedDeposit.getCode()){
            this.deposit.setInterestRate(standardsMap.get("DemandDepositInterestRate").getContent());
        }
        else{
            this.deposit.setInterestRate("0");
        }
        return this.deposit;
    }
    void initAccount(){
        this.account = new Account();
        this.account.setMoney("0");
        this.account.setSalt("000");
        this.account.setStatus(AccountTypeEnum.Deposit.getCode());
    }
    public Account getAccount(String accountId,String password){
        initAccount();
        this.account.setAccountId(accountId);
        this.account.setPassword(password);
        return this.account;
    }

    void initLoan(){
        this.loan = new Loan();
        this.loan.setStatus(LoanStatusEnum.APPROVING.getCode());
        this.loan.setInterestRate(standardsMap.get("LoanInterestRate").getContent());
        this.loan.setPaidMoney("0");
    }
    public Loan getLoan(LoanVo loanVo){
        initLoan();
        this.loan.setApproverId(loanVo.getApproverId());
        this.loan.setBorrowId(loanVo.getBorrowId());
        this.loan.setType(LoanTypeEnum.valueOf(loanVo.getType()).getCode());
        this.loan.setTotalMoney(loanVo.getTotalMoney().toString());
        this.loan.setCreatedTime(new Date());
        this.loan.setUpdatedTime(new Date());
        return this.loan;
    }
    void initTransfer(){
        this.transfer = new Transfer();
        this.transfer.setServiceCharge(standardsMap.get("TransferInterestRate").getContent());
    }
    public Transfer getTransfer(TransferVo transferVo){
        initTransfer();
        this.transfer.setFromId(transferVo.getFromId());
        this.transfer.setToId(transferVo.getToId());
        this.transfer.setType(TransferTypeNum.valueOf(transferVo.getType()).getCode());
        this.transfer.setMoney(transferVo.getMoney().toString());
        this.transfer.setRemarks(transferVo.getRemarks());
        this.transfer.setServiceCharge(transferVo.getServiceCharge().toString());
        this.transfer.setCreatedTime(new Date());
        this.transfer.setUpdatedTime(new Date());
        if(transfer.getType() == TransferTypeNum.RealTimeTransfer.getCode()){
            this.transfer.setStatus(TransferStatusNum.FINISHED.getCode());
        }else{
            this.transfer.setStatus(TransferStatusNum.ING.getCode());
        }
        return this.transfer;
    }
    void initFileConnect(){
        this.fileConnect = new FileConnect();
        this.fileConnect.setCreatedTime(new Date());
        this.fileConnect.setUpdatedTime(new Date());
    }
    public FileConnect getFileConnect(Long fileId,Long sourceId){
        initFileConnect();
        this.fileConnect.setFileId(fileId);
        this.fileConnect.setSourceId(sourceId);
        return this.fileConnect;
    }
    void initFile(){
        this.file = new File();
        this.file.setContent("loan");
        this.file.setType(FileTypeEnum.NORMAL.getCode());
        this.file.setCreatedTime(new Date());
        this.file.setUpdatedTime(new Date());
    }
    public File getFile(String name){
        initFile();
        this.file.setName(name);
        return this.file;
    }
    void initNotice(){
        this.notice = new Notice();
        this.notice.setTargetId(0l);
        this.notice.setCreatedTime(new Date());
        this.notice.setUpdatedTime(new Date());
    }
    public Notice getNotice(NoticeAddVo noticeAddVo){
        initNotice();
//        this.notice.setTargetId();
        this.notice.setTopic(noticeAddVo.getTitle());
        this.notice.setContent(noticeAddVo.getContent());
        return this.notice;
    }
    private void initStandard(){
        this.standard = new Standard();
    }
    public Standard getStandard(String name,String content){
        this.standard.setName(name);
        this.standard.setContent(content);
        return this.standard;
    }
    public Standard getStandard(StandardVo standardVo){
        this.standard.setName(standardVo.getName());
        this.standard.setContent(standardVo.getContent());
        return this.standard;
    }
}
